import {_decorator, Component, director, JsonAsset, macro, Node, PhysicsSystem2D, SpriteAtlas} from 'cc';
import {Constant} from '../../config/Constant';
import {logUtil} from "../../framework/util/logUtil";
import {AutoActorCon} from './AutoActorCon';
import {CoinCon} from './CoinCon';
import {AudioManager} from "../../framework/manager/AudioManager";
import {ResourceUtil} from "../../framework/util/ResourceUtil";
import {UIBuffGot} from '../../ui/layout/UIBuffGot';
import {UIBranchChoose} from '../../ui/layout/UIBranchChoose';
import {ActorActionManager} from '../../framework/manager/ActorActionManager';
import {UiManager} from "../../framework/manager/UiManager";
import {PlayerCon} from './PlayerCon';
import {ActorProperty} from "../entity/ActorProperty";
import {EffectCon} from './EffectCon';

const {ccclass, property} = _decorator;

/**
 * 关卡机制
 */
@ccclass('LevelCon')
export class LevelCon extends Component {
    private static _instance: LevelCon;
    private static scene: any;
    static get instance() {
        if (this._instance == null) {
            this.scene=director.getScene()
            this._instance = this.scene.getChildByPath(Constant.STATIC_NODE_PATH.UIGame).getComponent(LevelCon);
        }
        return this._instance;
    }

    //出生点
    @property(Node)
    spawnNode: Node | null = null;

    //终点
    @property(Node)
    destNode: Node | null = null;

    //日志控制器
    log = logUtil.instance
    logLevel = "LevelCon"

    //兵营
    //左
    forces1AutoActorCon: AutoActorCon | null = null;
    // 右
    forces2AutoActorCon: AutoActorCon | null = null;

    //金币系统
    coinCon: CoinCon | null = null;
    /**
     * 最大可存活的敌人数量
     */
    private test_maxAlive: number = Constant.GAME_SET.MaxAlive;

    //兵种按钮数据路径
    BranchJsonPath: string = Constant.DYNAMIC_RESOURCE.Data.BranchJsonPath
    BranchJson: any
    //光环按钮数据路径
    BuffJsonPath: string = Constant.DYNAMIC_RESOURCE.Data.BuffJsonPath
    BuffJson: any

    BuffPicPath: string = Constant.DYNAMIC_RESOURCE.Data.BuffPicPath
    BuffPlist: any
    //场景
    scene
    //资源数量
    GSpawn: number = Constant.GAME_SET.InitGSpawn;
    MSpawn: number = Constant.GAME_SET.InitMSpawn;
    WSpawn: number = Constant.GAME_SET.InitWSpawn;
    //游戏阶段
    stage: number=0
    //时间加强指数
    timeCount=0

    onLoad() {
        this.scene = director.getScene();
        this.log.log(this.logLevel, `onLoad`)
        PhysicsSystem2D.instance.enable = true
        this.init();

        this.node.on(Constant.EVENT_NAME.onBranchCreate, this.onBranchCreate, this)
    }

    onEnable() {
        this.log.log(this.logLevel, `onEnable`)
    }

    start() {
        this.log.log(this.logLevel, `start`)
    }

    restartGame(){
        this.timeCount=0
        //关卡信息
        this.node.emit(Constant.EVENT_NAME.initLevelInfo)
        //左上资源
        this.GSpawn=Constant.GAME_SET.InitGSpawn
        this.MSpawn=Constant.GAME_SET.InitMSpawn
        this.WSpawn=Constant.GAME_SET.InitWSpawn
        //zgnHelp 防御塔血量测试
        //region 两边防御塔
        this.activateTower(Constant.STATIC_NODE_PATH.Tower, 100);
        this.deactivateTower(Constant.STATIC_NODE_PATH.Tower_Destroyed);

        this.activateTower(Constant.STATIC_NODE_PATH.Wood_Tower, 100);
        this.deactivateTower(Constant.STATIC_NODE_PATH.Wood_Tower_Destroyed);
        //endregion

        //region 获得的buff
        EffectCon.instance.skillChoiceList=this.BuffJson
        EffectCon.instance.skillList=[]
        this.onBuffUpdate()
        //endregion

        //region 场景上的场景出生点上左右的节点清理
        this.deactivateFight(Constant.STATIC_NODE_PATH.Left)
        this.deactivateFight(Constant.STATIC_NODE_PATH.Right)
        this.forces1AutoActorCon.enemies=[]
        this.forces2AutoActorCon.enemies=[]
        // 初始化建筑
        this.forces1AutoActorCon.enemies.push(this.scene.getChildByPath(Constant.STATIC_NODE_PATH.Tower))
        this.forces2AutoActorCon.enemies.push(this.scene.getChildByPath(Constant.STATIC_NODE_PATH.Wood_Tower))
        //endregion

        if (director.isPaused()) {
            director.resume();
        }
    }
    //region 防御塔的启用禁用
    // 封装激活节点和设置属性的函数
    activateTower(nodePath: string, hp?: number) {
        let node = this.scene.getChildByPath(nodePath);
        node.active = true;
        if(hp){
            let actor=node.getComponent(ActorActionManager)
            actor.actorProperty.hp = hp;
            actor.updateHpBarUI();
        }
    }

    // 封装禁用节点的函数
    deactivateTower(nodePath: string) {
        let node = this.scene.getChildByPath(nodePath);
        node.active = false;
    }
    //endregion

    //region 战斗元素的禁用
    deactivateFight(nodePath: string){
        let sceneNode = this.scene.getChildByPath(nodePath).children;
        if(sceneNode.length>2){
            for (let i = 2; i < sceneNode.length; i++) {
                //对应对象池回收
                let isplay=sceneNode[i].getComponent(PlayerCon)
                if(isplay){
                    if(isplay.regime==Constant.DYNAMIC_RESOURCE.Actor.Forces1.Regime){
                        this.forces1AutoActorCon.enemyPools.free(sceneNode[i].name,sceneNode[i])
                    }else{
                        this.forces2AutoActorCon.enemyPools.free(sceneNode[i].name,sceneNode[i])
                    }
                    isplay.actor.respawn()
                }else{
                    this.coinCon.propPools.free(sceneNode[i].name,sceneNode[i])
                }
                //屏蔽节点
                sceneNode[i].active=false
            }
        }
    }
    //endregion

    onDestroy() {
        this.log.log(this.logLevel, `onDestroy`)
        this.node.off(Constant.EVENT_NAME.onBranchCreate, this.onBranchCreate, this);
    }

    //资源加载数据初始化
    async init() {
        //zgnHelp 资源加载时间优化
        //region 独立无关
        this.coinCon = new CoinCon(Constant.DYNAMIC_RESOURCE.Prop.Path)
        this.coinCon.init();

        AudioManager.instance.init();
        //endregion

        //region json
        ResourceUtil.loadResType(this.BranchJsonPath, JsonAsset).then(resource => {
            //可依据resource.name进行dir优化
            this.BranchJson = resource.json.RECORDS;
        })
        this.log.log('test_time', `BranchJson时间记录`)
        this.log.log('buff_test', `1.加载${this.logLevel}`);
        await ResourceUtil.loadResType(this.BuffJsonPath, JsonAsset).then(resource => {
            this.BuffJson = resource.json.RECORDS;
        })
        this.log.log('test_time', `BuffJson时间记录`)

        EffectCon.instance
        //endregion

        //region 小兵预制体
        //需要上述json数据
        this.forces1AutoActorCon = new AutoActorCon(Constant.DYNAMIC_RESOURCE.Actor.Forces1.Regime);
        this.forces1AutoActorCon.init();

        this.forces2AutoActorCon = new AutoActorCon(Constant.DYNAMIC_RESOURCE.Actor.Forces2.Regime);
        this.forces2AutoActorCon.init();
        this.log.log('test_time', `小兵预制体*2时间记录`)
        //endregion

        //region 图集
        this.BuffPlist=await ResourceUtil.loadResType(this.BuffPicPath, SpriteAtlas)
        this.log.log('test_time', `图集时间记录`)
        //endregion

        //region 按钮
        this.startSpawnTimer();
        //需要上述json数据和图集数据
        this.scene.getChildByPath(Constant.STATIC_NODE_PATH.UIBuffGot).getComponent(UIBuffGot).init();
        this.scene.getChildByPath(Constant.STATIC_NODE_PATH.UIBranchChoose).getComponent(UIBranchChoose).init();
        //endregion
    }

    /**
     * 怪物生成定时器-关卡核心
     * @demo
     */
    startSpawnTimer() {
        this.log.log(this.logLevel, `startSpawnTimer`)
        // 初始化建筑
        this.forces1AutoActorCon.enemies.push(this.scene.getChildByPath(Constant.STATIC_NODE_PATH.Tower))
        this.forces2AutoActorCon.enemies.push(this.scene.getChildByPath(Constant.STATIC_NODE_PATH.Wood_Tower))
        // 每1秒一次怪物,无限:macro.REPEAT_FOREVER(从0开始算1),0秒后,

        this.schedule(() => {
            this.timeCount++
            this.node.emit(Constant.EVENT_NAME.onBarrierUpdate,this.timeCount+1)
        }, 50, macro.REPEAT_FOREVER, 50)

        this.schedule(() => {
            this.randomSpawn(this.timeCount)
        }, 5, 100, 0)
    }

    onBranchCreate(branchName) {
        //映射BranchJson->branchId
        this.log.log(this.logLevel, `生成了${branchName}`)
        let cost=this.getBranchBataByName(branchName).cost
        if(cost>this.GSpawn){
            this.log.log(this.logLevel, `资源不足`)
            UiManager.instance.showDialog(Constant.DIALOG_DEF.UIShowTxt);
        }else{
            //消耗资源
            this.node.emit(Constant.EVENT_NAME.onResourceUpdate,
                0, cost, true
            )
            this.forces1AutoActorCon.FixedRole(branchName, this.spawnNode, this.destNode)
        }
    }

    /**
     * 获取特定name的数据信息
     * @param branchName {string} id
     * @author zgn
     */
    getBranchBataByName(branchName: string) {
        let result;
        for (let i = 0; i < this.BranchJson.length; i++) {
            result = this.BranchJson[i]
            if (result.name == branchName) {
                return result;
            }
        }
    }

    //随机生成怪物
    private randomSpawn(count:number) {
        let forces1 = this.forces1AutoActorCon.enemies.filter(element => element.active);

        let forces2 = this.forces2AutoActorCon.enemies.filter(element => element.active);

        if ((forces1.length + forces2.length) >= this.test_maxAlive) {
            return;
        }
        // this.forces1AutoActorCon.createRandomEnemy(this.spawnNode, this.destNode)
        let enhanceAttributes=new ActorProperty()
        enhanceAttributes.attack=1*count
        enhanceAttributes.hp=10*count
        this.log.log(this.logLevel, `加强${count}`);
        this.forces2AutoActorCon.createRandomEnemy(this.destNode, this.spawnNode,enhanceAttributes)
    }

    //zgnHelp ch2.获得随机buff
    gainBuff(event: Event, buffJsonData:any){
        EffectCon.instance.matchingSkill(buffJsonData)
        UiManager.instance.hideDialog(Constant.DIALOG_DEF.UIBuff);
        this.onBuffUpdate()
    }


    onBuffUpdate(){
        let ui=director.getScene().getChildByPath(Constant.STATIC_NODE_PATH.UIBuffGot).getComponent(UIBuffGot)
        ui.show()
    }
}


